Code First notes
If you get foriegn key contstraint errors when you use the convention of int 'TableNameId' in a class (in these cases if you do not submit a key id the Entity framework will try and put in a 0) just put ? after the int (int?) to tell the EF to allow nulls.
DBContext
You need to build a DbContext class along with your OO classes.
public class TempRxContext : DbContext
{
// You can add custom code to this file. Changes will not be overwritten.
//
// If you want Entity Framework to drop and regenerate your database
// automatically whenever you change your model schema, add the following
// code to the Application_Start method in your Global.asax file.
// Note: this will destroy and re-create your database with every model change.
//
//System.Data.Entity.Database.SetInitializer(new System.Data.Entity.DropCreateDatabaseIfModelChanges<ContosoUniversity.Models.ContosoUniversityContext>());
public DbSet<Address> Addresses { get; set; }
}
Check out this page in {0} translated from {1}translated fromOriginal:Translated:Automatic translation powered by Microsoft® TranslatorStart translatingStop translatingCloseClose and show original pageSelect
NOTE:
When the EF rebuilds your database remember to change your dates to date2s
You can force the creation of specifcs in your table with a map class
class
WorkHistoryMap : EntityTypeConfiguration<WorkHistory>
(example)
public WorkHistoryMap()
{
ToTable(
"WorkHistory");
HasKey(x => x.id);
Property(x => x.Name)
.HasColumnType(
"varchar")
.HasMaxLength(256)
.IsRequired();
HasRequired(x => x.User);
}
}
What to do if you get a null reference exception running Udate-Databse etc.
Uninstall - Microsoft Visual Studio 2010 ADO.NET Entity Framework Tools
For McvScaffolding
Make sure the your VS has the latest
MvcScaffolding by running
in NUGET
Install the scaffolding package.
Update-Package MvcScaffolding or
Install-Package MvcScaffolding
Good Blog post on using MvcScaffolding
http://blog.stevensanderson.com/2011/01/13/scaffold-your-aspnet-mvc-3-project-with-the-mvcscaffolding-package/
For Code first with data migrations
http://blogs.msdn.com/b/adonet/archive/2011/09/06/code-first-migrations-alpha-2-walkthrough.aspx
to get started get the latest version of the EF
In NuGet
Install-Package EntityFramework -IncludePrerelease
You may have to get the latest Nu-Get
You may have to restart after this command
Then in Nu-Get run
Enable-Migrations
This will create a folder in your project called migrations and a class called Configuration.cs. I this class you can put data for your tables that needs to be persisted during migrations.
NOTE: EACH TIME YOU RUN THIS IT REBUILDS YOUR CONFIGURATIONS.CS
Eg.
context.PharmacyExperiences.AddOrUpdate(
p => p.experience,
new PharmacyExperience { experience = "Retail" },
new
PharmacyExperience { experience = "Hospital" });
You can then run:
Add-Migration MyFirstMigration <-- whatever name you want
This will build a class for your tables in the migrations folder
Finally you run :
Update-Database
This will build out the database and add the seed data.
based on the connection string in your web.config
Note: this means we comment out the line in Global.asax.cs
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<TempRxContext>());
Troubleshooting
if you get 'you cannot call a method on a null-valued expression' when tryin to run the nuget commands, then restart VS
If you set
AutomaticMigrationsEnabled =
true;
in the Configuration consctructor then you can run Update-Database repeatedly.
Notes :
Remember after every migration to set all datatimes to datetime2
1. I have run into situations where in order to get the data to seed, you need to run Update-Database twice.
2. I have run into situations where I have had to comment out data migrations until the database has been created correctly due to the datetime2 problem.
3. I have even had to delete the db and run a dummy migration without the seed to get the db to build properly
4. If update failes due to contraints or indexes, delete the offender and rerun
MANY TO MANY DATA RELATIONSHIPS IN CODE FIRST / EF
To have the EF build many to many relationship tables put a list of objects in each of the objects that have the many to many relationship
EG.
public
class PharmacyExperience
{
[
Key]public int id { get; set; }
public string experience { get; set; }
public virtual ICollection<ContratorProfile> contratorProfiles { get; set; } <---
}
public
class ContratorProfile
{
[
Key]publicint id { get; set; }
public bool felony { get; set; }
public bool citizen { get; set; }
public bool workStatus { get; set; }
public virtual ICollection<License> licenses { get; set; }
public virtual ICollection<WorkHistory> workHistorys { get; set; }
public virtual ICollection<PharmacyExperience> PharmacyExperiences { get; set; }<---
public virtual ICollection<LevelOfEducation> LevelOfEducations { get; set; }
public virtual ICollection<PlacementPreference> PlacementPreferences { get; set; }
}
Will give you (among other things) a table called
PharmacyExperienceContratorProfiles
Good blog
In order to change the objects to correctly create the associations in the db schema and to get the *many-valued* associations working... like those objects that must maintain collections or lists of other objects.
On this page, scroll down just a bit to the section header "Code First And Associations" to see links to the Association tutorials. I think this blog is pretty easy to understand compared to many I've seen!
http://weblogs.asp.net/manavi/archive/2011/03/27/associations-in-ef-4-1-code-first-part-1-introduction-and-basic-concepts.aspx
Foriegn key relationships
Foriegn key relationships you need to define the object relationships in you classes with a virtual
eg.
public
virtual Contractor contractor { get; set; }
otherwise the objects will appear as null when you 'get' and object from the db.
you can also use
[ForeignKey("Customer")]
public string CustomerID {get;set;}
as a decorator
Scaffolding in MVC3
There are new capabilities for scaffolding in MVC3
Using NUGet
Install-Package MvcScaffolding
Get the capabilities:
Get-DefaultScaffolder
Generate the Controller and Views and the DBContext object from a class
Scaffold Controller Categories <-- categories is a class
Note: If you want the scaffolder to automagically build out your drop downs then add the attribute to your class for the foriegn key as well as the list .
eg.
public
int PositionId { get; set; } <-- this references the 'id' column in the Positions table
public virtual Position position { get; set; } <-- this builds the foriegn key in the host table
Notes on attributes that can be added to your Classes in the Model to be formatted in the scaffolder.
This attribute formats output
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:d}")]
This attribute will cause atext area to be built.
[
DataType(DataType.MultilineText)]
[ScaffoldColumn(false)] works for standard MVC scaffolding but not for NuGet scaffolding
-------------------------------------------------
Default Values
You can add default values in the constructor of the class
eg.
public class Job
{
public Job()
{
this.datePosted = DateTime.Now;
}
This will translate into a constraint on the table like :
USE [TempRxTest]
GO
ALTER TABLE [dbo].[Jobs] ADD CONSTRAINT [DF_Jobs_datePosted] DEFAULT (getdate()) FOR [datePosted]
GO
To handle the 'There is already an open DataReader'
This might happen when you scaffold a complex page .
To fix add this to you connection string.
MultipleActiveResultSets = true